#ifndef _GAMEVIEW_H_
#define _GAMEVIEW_H_

#include <map>
#include <vector>

#include "glfw.h"
#include "vmath.h"

#include "gamemodel.h"
#include "igamestateview.h"
#include "objmodel.h"
#include "camera.h"
#include "guisystem.h"


class GameView : public IGameStateView
{
public:
    GameView(GameModel& model, GuiSystem& gui);
    ~GameView();

    void draw(bool clear);
    void onEnter();

    Camera& getCamera();

    bool getClickedSquare(int wndX, int wndY, int* squareX, int* squareY);

    void showMouseMarker(int x, int y);
    void hideMouseMarker();
    void highlightMoves(int playerX, int playerY);
    void clearHighlights();

    // Regenerates piece list
    void updateBoard();

    // Regenerates piece list & starts animations based on move
    void animateMove(const Move& m);

    // Updates animations
    void updateAnimations(float dt);

    // Is view idle or doing something, eg. running an animation
    bool isReady();

    // Resets the view to the default state
    void reset();

private:

    // Animation types
    enum AnimType {
        AT_NONE = 0,
        AT_MOVE,
        AT_DELETE
    };

    // Class for storing animation info etc for pieces
    class PieceInfo
    {
    public:
        int _type;  // Piece type
        Matrix4f _trans;    // Transformation matrix
        int _x0, _y0;   // Animation start (or current position)
        int _x1, _y1;   // Animation end
        float _t;   // Animation position (0.0 = start, 1.0 = end)
        AnimType _anim; // Animation type
        bool _hide; // If true piece is not drawn
    };

    // Highlight types
    enum HighlightType {
        HLT_MOVE = 0,
        HLT_SELF,
        HLT_ATTACK,
        HLT_CASTLE
    };

    // Class for info about highlighted square
    class HighlightInfo
    {
    public:
        HighlightType _type;
        int _x, _y;
    };


    void drawModel(ObjModel& model, Matrix4f& matrix, bool isTrans = false,
                   float t = 0.0f);
    void drawAxes(Vector3f position, float length);
    void drawHighlight(int squareX, int squareY, HighlightType type);
    void drawMouseMarker();

    void setup3dView();
    void setup2dView();

    // Converts squares (0-7) to object coordinates
    float squareToObj(int square);

    // Updates translation matrix for piece based on animation, color etc
    void updateMatrixForPiece(PieceInfo& p);

    Camera _camera;
    int _wndWidth, _wndHeight;

    GameModel& _model;
    GuiSystem& _gui;

    static const GuiId GUI_HOURGLASS = 999;
    static const GuiId GUI_WHITEWON = 998;
    static const GuiId GUI_BLACKWON = 997;

    // Piece models
    std::map<int, ObjModel*> _pieceModels;

    // Board model
    ObjModel _boardModel;

    // List of pieces currently on the board
    std::vector<PieceInfo> _pieces;

    // List of active highlights
    std::vector<HighlightInfo> _highlights;

    // Background image texture
    Texture _bgTexture;

    // Mouse hover texture
    Texture _mouseTexture;

    // True if there are animations running
    bool _animation;

    // Animation speed
    const float _animSpeed;

    // Draw mouse marker
    bool _drawMouse;

    // Last mouse position in object coordinates
    float _mouseX, _mouseY;

};

#endif // _GAMEVIEW_H_
